/******************************************************************************
 * Product: Adempiere ERP & CRM Smart Business Solution                       *
 * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.                *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program is distributed in the hope   *
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.           *
 * See the GNU General Public License for more details.                       *
 * You should have received a copy of the GNU General Public License along    *
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.                     *
 * For the text or an alternative of this public license, you may reach us    *
 * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA        *
 * or via info@compiere.org or http://www.compiere.org/license.html           *
 *****************************************************************************/
package org.compiere.acct;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.util.ArrayList;

import org.compiere.model.MAccount;
import org.compiere.model.MAcctSchema;
import org.compiere.model.MAsset;
import org.compiere.model.MAssetTransaction;
import org.compiere.model.MAssetTransactionLine;
import org.compiere.util.Env;

/**
 *  Post Asset Transaction Document.
 *  <pre>
 *  Table:              A_Asset_Transaction (321)
 *  Document Types:     AAA
 *  </pre>
 *  @author Duman Zhunissov
 */
public class Doc_AssetTransaction extends Doc
{
//	private String			m_DocStatus = "";
	
	/**
	 *  Constructor
	 * 	@param ass accounting schemata
	 * 	@param rs record
	 * 	@param trxName trx
	 */
	public Doc_AssetTransaction (MAcctSchema[] ass, ResultSet rs, String trxName)
	{
		super (ass, MAssetTransaction.class, rs,  null, trxName);
	}   //  Doc_AssetTransaction

	/**
	 *  Load Document Details
	 *  @return error message or null
	 */
	protected String loadDocumentDetails()
	{
		setC_Currency_ID (NO_CURRENCY);
		MAssetTransaction assettrans = (MAssetTransaction)getPO();
		setDateDoc (assettrans.getDateAcct());
		setDateAcct(assettrans.getDateAcct());
		//m_Reversal_ID = assettrans.getReversal_ID();//store original (voided/reversed) document
		//m_DocStatus = assettrans.getDocStatus();
		//	Contained Objects
		p_lines = loadLines(assettrans);
		log.fine("Lines=" + p_lines.length);
		return null;
	}   //  loadDocumentDetails

	/**
	 *	Load Asset Transaction Line
	 *	@param AssetTransaction AssetTransaction
	 *  @return DocLine Array
	 */
	private DocLine[] loadLines(MAssetTransaction assettrans)
	{
		ArrayList<DocLine> list = new ArrayList<DocLine>();
		if (getDocumentType().equals(DOCTYPE_AAScrap)) { 
			MAssetTransactionLine[] lines = assettrans.getLines(false);
			for (int i = 0; i < lines.length; i++)
			{
				MAssetTransactionLine line = lines[i];
				DocLine docLine = new DocLine (line, this); 
				MAsset asset = new MAsset(getCtx(), line.getA_Asset_ID(), getTrxName());
				BigDecimal AssetAmt = null;
				BigDecimal DeprAmt = null;
				BigDecimal Qty = null;
				AssetAmt = line.getAssetAmt();
				DeprAmt = line.getDeprAmt();
				Qty = line.getQty();
				BigDecimal diffAmt = AssetAmt.subtract(DeprAmt);
				//	nothing to post
				if (AssetAmt.compareTo(Env.ZERO) == 0 && DeprAmt.compareTo(Env.ZERO) == 0
						&& Qty.compareTo(Env.ZERO) == 0)
					continue;
				if (Qty.signum() != 0)	Qty = Qty.negate();		//	Internal Use entered positive
				log.fine(docLine.toString());
				if (diffAmt.compareTo(Env.ZERO)!=0) {
					docLine.setAmount(Env.ZERO, diffAmt.abs());
					docLine.setAccount(MAccount.get (getCtx(),asset.getAcctValue("A_Asset_Acct")));
					list.add (docLine);
					docLine = new DocLine (line, this); 
					docLine.setAmount(diffAmt.abs(), Env.ZERO);
					docLine.setAccount(MAccount.get (getCtx(),asset.getAcctValue("A_Disposal_Loss")));
					list.add (docLine);
				}	
				if (DeprAmt.compareTo(Env.ZERO)!=0) { //
					docLine = new DocLine (line, this); 
					docLine.setAmount(Env.ZERO, DeprAmt.abs());
					docLine.setAccount(MAccount.get (getCtx(),asset.getAcctValue("A_Asset_Acct")));
					list.add (docLine);
					docLine = new DocLine (line, this);
					docLine.setAmount(DeprAmt.abs(), Env.ZERO);
					docLine.setAccount(MAccount.get (getCtx(),asset.getAcctValue("A_Accumdepreciation_Acct")));
					list.add (docLine);
				}	
			}
		}
		else if (getDocumentType().equals(DOCTYPE_AAImport)) {
			MAssetTransactionLine[] lines = assettrans.getLines(false);
			MAssetTransactionLine line = lines[0];
			DocLine docLine = new DocLine (line, this); 
			docLine.setAmount(Env.ZERO, Env.ZERO);
			list.add (docLine);
		}
		//---
		else if (getDocumentType().equals(DOCTYPE_AATransfer)){
			MAssetTransactionLine[] lines = assettrans.getLines(false);
			for (int i = 0; i< lines.length; i++){
				
				MAssetTransactionLine line = lines[i];
				DocLine docLine = new DocLine (line, this); 
				MAsset asset1 = new MAsset(getCtx(), line.getA_Asset_ID(), getTrxName());
				
				docLine.setAmount(Env.ZERO, line.getAssetAmt().abs() );
				docLine.setAccount(MAccount.get (getCtx(),asset1.getAcctValue("A_Asset_Acct")));
				list.add(docLine);
				
				docLine = new DocLine(line, this);
				MAsset asset2 = new MAsset(getCtx(), line.getA_Asset2_ID(), getTrxName());
				docLine.setAmount(line.getAssetAmt().abs() , Env.ZERO);
				docLine.setAccount(MAccount.get(getCtx(), asset2.getAcctValue("A_Asset_Acct")));
				list.add(docLine);
				
				if(line.getDeprAmt().compareTo(Env.ZERO)!=0)
				{
					docLine = new DocLine(line, this);
					docLine.setAmount(line.getDeprAmt().abs(), Env.ZERO );
					docLine.setAccount(MAccount.get (getCtx(),asset1.getAcctValue("A_Accumdepreciation_Acct")));
					list.add(docLine);
					
					docLine = new DocLine(line, this);
					docLine.setAmount(Env.ZERO, line.getDeprAmt().abs());
					docLine.setAccount(MAccount.get(getCtx(), asset2.getAcctValue("A_Accumdepreciation_Acct")));
					list.add(docLine);
				}
			}
		}
		else if (getDocumentType().equals(DOCTYPE_AACorrection)){
			MAssetTransactionLine[] lines = assettrans.getLines(false);
			for (int i = 0; i< lines.length; i++){
				
				MAssetTransactionLine line = lines[i];
				MAsset asset = new MAsset(getCtx(), line.getA_Asset_ID(), getTrxName());
				
				if(line.getDeprAmt().compareTo(Env.ZERO)!=0)
				{
					DocLine docLine = new DocLine (line, this); 
					docLine.setAmount(line.getDeprAmt(), Env.ZERO );
					docLine.setAccount(MAccount.get (getCtx(),asset.getAcctValue("A_Depreciation_Acct")));
					list.add(docLine);
					
					docLine = new DocLine(line, this);
					docLine.setAmount(Env.ZERO, line.getDeprAmt());
					docLine.setAccount(MAccount.get(getCtx(), asset.getAcctValue("A_Accumdepreciation_Acct")));
					list.add(docLine);
				}
			}
		}	
		//---
		//	Return Array
		DocLine[] dls = new DocLine[list.size()];
		list.toArray(dls);
		return dls;
	}	//	loadLines

	/**
	 *  Get Balance
	 *  @return Zero (always balanced)
	 */
	public BigDecimal getBalance()
	{
		BigDecimal retValue = Env.ZERO;
		return retValue;
	}   //  getBalance

	/**
	 *  Create Facts (the accounting logic) for
	 *  AAS.
	 *  <pre>
	 *  Asset Transaction
	 *  </pre>
	 *  @param as account schema
	 *  @return Fact
	 */
	public ArrayList<Fact> createFacts (MAcctSchema as)
	{
		//  create Fact Header
		ArrayList<Fact> facts = new ArrayList<Fact>();
		if (getDocumentType().equals(DOCTYPE_AAScrap)) { 
			Fact fact = new Fact(this, as, Fact.POST_Actual);
			setC_Currency_ID(as.getC_Currency_ID());

			for (int i = 0; i < p_lines.length; i++)
			{
				DocLine line = p_lines[i];
				fact.createLine(line, line.getAccount(),
						as.getC_Currency_ID(), line.getAmtSourceDr(), line.getAmtSourceCr());
			}
			facts.add(fact);
		}
		//----
		else if (getDocumentType().equals(DOCTYPE_AATransfer)){
			Fact fact = new Fact(this, as, Fact.POST_Actual);
			setC_Currency_ID(as.getC_Currency_ID());

			for (int i = 0; i < p_lines.length; i++)
			{
				DocLine line = p_lines[i];
				fact.createLine(line, line.getAccount(), as.getC_Currency_ID(), line.getAmtSourceDr(), line.getAmtSourceCr());
			}
			facts.add(fact);
		}
		else if (getDocumentType().equals(DOCTYPE_AACorrection)){
			Fact fact = new Fact(this, as, Fact.POST_Actual);
			setC_Currency_ID(as.getC_Currency_ID());

			for (int i = 0; i < p_lines.length; i++)
			{
				DocLine line = p_lines[i];
				fact.createLine(line, line.getAccount(), as.getC_Currency_ID(), line.getAmtSourceDr(), line.getAmtSourceCr());
			}
			facts.add(fact);
		}
		//----
		return facts;
	}   //  createFact

}   //  Doc_AssetTransaction
